package pcloud.client.scheduler;

import java.lang.Thread.State;
import java.util.LinkedList;
import java.util.Queue;

import pcloud.client.util.Logger;
import pcloud.client.worker.CloudTask;

public class EventMonitor implements Runnable, EventMonitorInterface 
{
    private Queue<CloudEvent> eventQueue = new LinkedList<CloudEvent>();
    private TaskScheduler taskScheduler;
    volatile boolean monitorOn;
    private Thread monitorThread;

    public EventMonitor(TaskScheduler taskScheduler)
    {
        this.taskScheduler = taskScheduler;
        monitorThread = new Thread(this);
    }

    /* (non-Javadoc)
	 * @see pcloud.client.scheduler.EventMonitorInterface#start()
	 */
    public void start()
    {
        monitorOn = true;
        State state = monitorThread.getState();
		logger.info("Monitor starting, current state: " + state);

        if ( state.equals(State.TERMINATED) || state.equals(State.NEW) ) {
            monitorThread.start();
        }
    }
    /* (non-Javadoc)
	 * @see pcloud.client.scheduler.EventMonitorInterface#raiseEvent(pcloud.client.scheduler.CloudEvent)
	 */
    public void raiseEvent(CloudEvent theEvent)
    {
		logger.info("Event raising: " + theEvent.toString());
        if (monitorOn) {
        	synchronized  (eventQueue) {
                eventQueue.offer(theEvent);
				logger.info("Event Monitored: " + theEvent.toString());
            }
        } else {
			logger.info("Event Abandoned: " + theEvent.toString());
        }
    }

    private void saveEventQueue()
    {
        while ( !eventQueue.isEmpty() ) {
            CloudEvent theEvent = eventQueue.poll();
			logger.info("Event Save: " + theEvent.toString());
        }
    }
    /* (non-Javadoc)
	 * @see pcloud.client.scheduler.EventMonitorInterface#stop()
	 */
    public void stop()
    {
        monitorOn = false;
    }

	@Override
	public void run()
	{
		logger.info("handleEvent thread started!");

        while (monitorOn) {
            synchronized (eventQueue) {
                if (eventQueue.isEmpty() ) {
                    try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
                    continue;
                }
                CloudEvent theEvent = eventQueue.poll();
                CloudTask cloudTask = theEvent.handle();
                taskScheduler.add(cloudTask);

				logger.info("Event Handled: " + theEvent.toString());

            }
            try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
        }
        this.saveEventQueue();
        logger.info("handleEvent thread ended!");

	}

}
